home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
NOVA - For the NeXT Workstation
/
NOVA - For the NeXT Workstation.iso
/
SourceCode
/
AdobeExamples
/
NX_Patterns
/
Pattern.m
< prev
next >
Wrap
Text File
|
1992-12-19
|
10KB
|
403 lines
/*
* (a) (C) 1990 by Adobe Systems Incorporated. All rights reserved.
*
* (b) If this Sample Code is distributed as part of the Display PostScript
* System Software Development Kit from Adobe Systems Incorporated,
* then this copy is designated as Development Software and its use is
* subject to the terms of the License Agreement attached to such Kit.
*
* (c) If this Sample Code is distributed independently, then the following
* terms apply:
*
* (d) This file may be freely copied and redistributed as long as:
* 1) Parts (a), (d), (e) and (f) continue to be included in the file,
* 2) If the file has been modified in any way, a notice of such
* modification is conspicuously indicated.
*
* (e) PostScript, Display PostScript, and Adobe are registered trademarks of
* Adobe Systems Incorporated.
*
* (f) THE INFORMATION BELOW IS FURNISHED AS IS, IS SUBJECT TO
* CHANGE WITHOUT NOTICE, AND SHOULD NOT BE CONSTRUED
* AS A COMMITMENT BY ADOBE SYSTEMS INCORPORATED.
* ADOBE SYSTEMS INCORPORATED ASSUMES NO RESPONSIBILITY
* OR LIABILITY FOR ANY ERRORS OR INACCURACIES, MAKES NO
* WARRANTY OF ANY KIND (EXPRESS, IMPLIED OR STATUTORY)
* WITH RESPECT TO THIS INFORMATION, AND EXPRESSLY
* DISCLAIMS ANY AND ALL WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR PARTICULAR PURPOSES AND NONINFRINGEMENT
* OF THIRD PARTY RIGHTS.
*/
/*
* Pattern.m
*
* This class provides objects that correspond to patterns. It is modeled after the
* Font class. It not a rigorous definition but is just a vehicle for demostrating the
* PostScript aspects of handling patterns.
*
* Version: 2.0
* Author: Ken Fromm
* History:
* 03-07-91 Added this comment.
*/
#import "Pattern.h"
#import "PSWpatterns.h"
#import "PSWpatternsdemo.h"
#import "PSWsamples.h"
#import "PatternApp.h"
#import <appkit/Font.h>
#import <appkit/Matrix.h>
#import <appkit/Panel.h>
#import <appkit/View.h>
#import <appkit/nextstd.h>
#import <objc/hashtable.h>
#import <dpsclient/wraps.h>
#import <dpsclient/dpsclient.h>
@implementation Pattern : Object
+ initialize
{
PSWPatternDefs();
PSWPatternDemoDefs();
PSWPatternOctagon();
PSWPatternCircleStar();
PSWPatternWeave();
PSWPatternBrick();
return self;
}
+ newPattern:(const char *) patternName size:(float) patternSize
{
return [Pattern newPattern:patternName size:patternSize matrix:NX_IDENTITYMATRIX];
}
+ newPattern:(const char *) patternName size:(float) patternSize matrix:(const float *) patternMatrix
{
self = [super new];
name = NXCopyStringBuffer(patternName);
size = patternSize;
if (name && size)
{
if (patternMatrix == NX_IDENTITYMATRIX)
pFlags._matrixIsIdentity = YES;
else if (patternMatrix == NX_FLIPPEDMATRIX)
pFlags._matrixIsFlipped = YES;
else
matrix = (float *) patternMatrix;
}
return self;
}
- free
{
[image free];
PSundefineuserobject(patternNum);
PSundefineuserobject(patternImageNum);
return [super free];
}
/*
* This method is only here to vary the number of pattern
* images in a cell in order to generate the different test cases.
* In a real implementation, one value would be chosen
* as the optimal number of images per cell and to use this
* value in the +new methods to define the pattern there.
*
* Twice the width and height plus an additional number is used
* for the window size. The first cell is drawn at the origin of the
* image window. In many cases, part of this cell will be drawn outside
* the window resulting in an imcomplete image. The second cell
* is drawn entirely within the window. It is that cell that is used for
* compositing. Two time the width and height provides the room for
* the second cell. The 2 adds a little spacing so that the image does
* not lie on the edge of the window boundary.
*
* This type of manipulation is necessary because patterns
* are locked down to device space which in this case is window
* space.
*/
- definePatternRows:(int) rows andCols:(int) cols
{
volatile BOOL ok = NO;
int available;
float r, g, b;
float aMatrix[6];
float *aMatrixPtr;
NXRect imageRect;
if (name && size && rows && cols)
{
if (pFlags._matrixIsIdentity || pFlags._matrixIsFlipped || !matrix)
{
bzero(aMatrix, sizeof(aMatrix));
aMatrix[0] = size;
if (pFlags._matrixIsFlipped)
aMatrix[3] = -size;
else
aMatrix[3] = size;
aMatrixPtr = aMatrix;
}
else
aMatrixPtr = matrix;
NX_DURING
PSWCheckPattern(name, &available);
if (available)
{
/********************************************************/
/*
* Only used to give the compositing image the current color.
* Unnecessary in a real implementation of patterns.
*/
PScurrentrgbcolor(&r, &g, &b);
/*
* If locking to window, then forego the PatternViewDict.
*/
PSWBeginPattern();
PSWBeginPatternView();
PSWExpandPattern(name, aMatrixPtr, rows, cols);
PSend();
PSend();
patternNum = DPSDefineUserObject(0);
/********************************************************/
/*
* This portion is used to get the image for compositing.
* The composite approach is not recommended for a
* real implementation and so this portion is unnecessary.
*/
if (patternNum)
{
PSWBeginPattern();
PSWSizeImage(patternNum, &cellRect.origin.x,
&cellRect.origin.y, &cellRect.size.width,
&cellRect.size.height);
PSend();
imageRect = cellRect;
imageRect.size.width = imageRect.size.width * 2 + 2;
imageRect.size.height = imageRect.size.height * 2 + 2;
image = [Panel newContent:&imageRect
style:NX_TITLEDSTYLE
backing:NX_RETAINED
buttonMask:NX_CLOSEBUTTONMASK
defer:NO];
[[image contentView] setFlipped:NO];
[[image contentView] lockFocus];
PSsetrgbcolor(r, g, b);
PSWBeginPattern();
PSWMakeImage(patternNum);
PSend();
patternImageNum = DPSDefineUserObject(0);
[[image contentView] unlockFocus];
}
/********************************************************/
ok = YES;
}
NX_HANDLER
NX_ENDHANDLER
}
if (!ok)
{
if (!available)
NXRunAlertPanel("Pattern", "Pattern dictionary not available.", "OK", NULL, NULL);
else
NXRunAlertPanel("Pattern", "Error while defining pattern", "OK", NULL, NULL);
return nil;
}
return self;
}
/*************************************************************/
/*
* The next two methods - image and compositeTo::
* provide information and perform operations for
* demonstration purposes.
*/
/*
* This method returns the window holding the image.
* It can be inserted into the window list to show how
* the image is cached.
*/
- image
{
return image;
}
/*
* Composite the center of the pattern cell to the point
* (x, y) in the currently focused view.
*/
- compositeTo:(NXCoord) x :(NXCoord) y
{
PSWCompositePattern(patternNum, patternImageNum, x, y);
return self;
}
/*************************************************************/
- (BOOL) hasMatrix
{
if (matrix)
return YES;
return NO;
}
- (const float *) matrix
{
return matrix;
}
- (const char *) name
{
return name;
}
- (int) patternNum
{
return patternNum;
}
- (float) pointSize
{
return size;
}
/*
* Place the pattern dictionary on top of the dictionary stack.
* The pattern dictionary contains redefinition of the drawing and
* showing operators to emulate the pattern operators in Level 2.
* This emulation turns patterns into fonts thereby taking advantage
* of the font cache.
*
* The DrawingStatus variable performs the same function as the
* NXDrawingStatus variable except that the trigger is the
* composite-font radio buttons in the drawing options panel and
* not the actual drawing status.
*/
- set
{
int type, lock;
/********************************************************/
/* Demonstration program only. */
type = [[NXApp typeMatrix] selectedTag];
lock = [[NXApp lockMatrix] selectedTag];
/********************************************************/
if (patternNum)
{
PSWBeginPattern();
PSWSetPattern(patternNum);
/*
* Only necessary if locking to view. The "lock == ..."
* checks are only for the demostration program.
*/
if (NXDrawingStatus == NX_DRAWING &&
(lock == LOCK_VIEW || lock == LOCK_VIEWSCALE))
{
PSWBeginPatternView();
if (lock == LOCK_VIEWSCALE)
PSWBeginPatternViewScale();
}
/********************************************************/
/* Demonstration program only. */
if (type == TYPE_DRAW)
{
PSWBeginPatternDraw();
}
else if (patternImageNum && type == TYPE_COMP)
{
PSWBeginPatternImage();
PSWSetPatternImage(patternImageNum);
}
/********************************************************/
/*
* Place a copy of userdict on the stack
*/
PSuserdict();
PSbegin();
}
return self;
}
/*
* This method is necessary for emulation of the setpattern in Level 2.
* If the font method for patterns is being used, then this method removes
* the definitions that replace the regular drawing and showing operators.
*/
- unset
{
int type, lock;
/********************************************************/
/* Demonstration program only. */
type = [[NXApp typeMatrix] selectedTag];
lock = [[NXApp lockMatrix] selectedTag];
/********************************************************/
if (patternNum)
{
PSend(); /* Userdict */
/********************************************************/
/* Demonstration program only. */
/* PatternDrawDict or PatternImageDict */
if (type == TYPE_DRAW || (patternImageNum && type == TYPE_COMP))
PSend();
/********************************************************/
if (NXDrawingStatus == NX_DRAWING)
/*
* If locking to view than pop the PatternViewDict off the
* dictionary stack and the PatternViewScaleDict if it is
* also on the stack. Once the locking type has been
* decided, the "lock == ..." checks are not necessary.
* Only the NXDrawingStatus check should remain.
*/
if (NXDrawingStatus == NX_DRAWING &&
(lock == LOCK_VIEW || lock == LOCK_VIEWSCALE))
{
PSend();
if (lock == LOCK_VIEWSCALE)
PSend();
}
PSWUnsetPattern();
PSend(); /* PatternDict */
}
return self;
}
@end